﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BeanOverflow.Models;
using System.Web.Security;
using System.Data.Entity.Validation;
using System.Diagnostics;
using System.Data.Entity.Infrastructure;

namespace BeanOverflow.Controllers
{ 
    public class MemberProfileController : Controller
    {
        private MemberProfileDBContext db = new MemberProfileDBContext();
        private QuestionDBContext qdb = new QuestionDBContext();
        private ResponseDBContext rdb = new ResponseDBContext();

        //
        // GET: /MemberProfile/
        /// <summary>
        /// Displays profile of the current user
        /// </summary>
        /// <returns>an ActionResult - redirects to the logged in user's profile page</returns>
        [Authorize]
        public ActionResult Index()
        {
            MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
            return RedirectToAction("Details", "MemberProfile", new { id = currentUser.UserName });
        }

        //
        // GET: /MemberProfile/Details/5
        /// <summary>
        /// Displays profile of the user specified by id
        /// </summary>
        /// <returns>View of the user's profile</returns>
        [Authorize]
        public ViewResult Details(string id)
        {
            MemberProfile memberprofile = db.MemberProfiles.Find(id);
            MembershipUser member = Membership.GetUser(id);
            ViewBag.userEmail = member.Email;
            ViewBag.responseCount = getResponseCountForUser(id);
            ViewBag.questionsAskedCount = getQuestionCountForUser(id);
            return View(memberprofile);
        }

        /// <summary>
        /// Get the number of questions asked by a user
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        private int getQuestionCountForUser(String userId)
        {
            var questions = from m in qdb.Questions
                            select m;
            questions = questions.Where(s => s.UserName.Equals(userId));
            return questions.Count();
        }

        /// <summary>
        /// Get the number of responses provided by a user
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        private int getResponseCountForUser(String userId)
        {
            var responses = from m in rdb.Responses
                            select m;
            responses = responses.Where(s => s.UserName.Equals(userId));
            return responses.Count();
        }

        //
        // GET: /MemberProfile/Image/5
        /// <summary>
        /// Fetches the user's image from the database specified by id
        /// </summary>
        /// <returns>image of the user</returns>
        [Authorize]
        public FileContentResult Image(string id)
        {
            MemberProfile memberprofile = db.MemberProfiles.Find(id);

            if (memberprofile != null && memberprofile.ImageData != null)
            {
                return new FileContentResult(memberprofile.ImageData, memberprofile.ImageMimeType);
            }
            return null;
        }

        //
        // GET: /MemberProfile/Create

        //public ActionResult Create()
        //{
        //    return View();
        //} 

        //
        // POST: /MemberProfile/Create

        //[HttpPost]
        //public ActionResult Create(MemberProfile memberProfile)
        //{
        //    if (ModelState.IsValid)
        //    {
        //        db.MemberProfiles.Add(memberProfile);
        //        db.SaveChanges();
        //        return RedirectToAction("Index");  
        //    }

        //    return View(memberProfile);
        //}
        
        //
        // GET: /MemberProfile/Edit/5
        /// <summary>
        /// Gets the edit view of the profile if the id of the user matches the current user
        /// </summary>
        /// <returns>edit view of the user profile</returns>
        [Authorize]
        public ActionResult Edit(string id)
        {
            MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
            if (currentUser.UserName == id)
            {
                MemberProfile memberprofile = db.MemberProfiles.Find(id);
                MembershipUser member = Membership.GetUser(id);
                ViewBag.userEmail = member.Email;
                return View(memberprofile);
            }
            else
            {
                //we don't display the edit link if a user is viewing someone else's profile
                //but just in case if they manage to get here
                return RedirectToAction("Details", "MemberProfile", new { id = id });
            }
        }

        //
        // POST: /MemberProfile/Edit/5

        [HttpPost]
        [Authorize]
        public ActionResult Edit(MemberProfile memberProfile, HttpPostedFileBase image)
        {
            if (ModelState.IsValid)
            {
                //save the image if it is not null
                if (image != null)
                {
                    memberProfile.ImageMimeType = image.ContentType;
                    memberProfile.ImageData = new byte[image.ContentLength];
                    image.InputStream.Read(memberProfile.ImageData, 0, image.ContentLength);
                    db.Entry(memberProfile).State = EntityState.Modified;
                }
                else
                {
                    //if image is null, resave original image
                    MemberProfile origMemberProfile = db.MemberProfiles.Find(memberProfile.UserId);
                    origMemberProfile.Bio = memberProfile.Bio;
                    origMemberProfile.companyId = memberProfile.companyId;
                    origMemberProfile.Position = memberProfile.Position;
                    origMemberProfile.role = memberProfile.role;
                    db.Entry(origMemberProfile).State = EntityState.Modified;
                }
                
                try
                {
                    db.SaveChanges();
                }
                catch (DbEntityValidationException dbEx)
                {
                    foreach (var validationErrors in dbEx.EntityValidationErrors)
                    {
                        foreach (var validationError in validationErrors.ValidationErrors)
                        {
                            Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
                        }
                    }
                }


                return RedirectToAction("Index");
            }
            return View(memberProfile);
        }

        //
        // GET: /MemberProfile/Delete/5
        //users can't be deleted at the moment
        //public ActionResult Delete(string id)
        //{
        //    MemberProfile memberprofile = db.MemberProfiles.Find(id);
        //    return View(memberprofile);
        //}

        //
        // POST: /MemberProfile/Delete/5
        //can't delete users at the moment
        //[HttpPost, ActionName("Delete")]
        //public ActionResult DeleteConfirmed(string id)
        //{            
        //    MemberProfile memberprofile = db.MemberProfiles.Find(id);
        //    db.MemberProfiles.Remove(memberprofile);
        //    db.SaveChanges();
        //    return RedirectToAction("Index");
        //}

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}